#!/usr/bin/env python
#-IMPORTS-----------------------------------------------------------------------
import os
import time
import cmdline
import threading
import subprocess
#-CLASSES-----------------------------------------------------------------------
class Worker(threading.Thread):
    """A worker thread.
    """
    def __init__(self, p_input, p_output, p_cmgr):
        self.__get_job = p_input.get
        if p_output:
            self.__put_job = p_output.put
        self.__cmgr = p_cmgr
        threading.Thread.__init__(self)

    def __get_output(self, p_cmd = None):
        if p_cmd is None:
            return False
        so = p_cmd.proc.recv()
        se = p_cmd.proc.recv_err()
        if so is not None:
            p_cmd.rettxt += ''.join(so)
        if se is not None:
            p_cmd.errtxt += ''.join(se)
        return True

    def _process_job(self, p_cmd):
        """Spawn out and execute the command.
        """
        exe = p_cmd.s_cmd.split(' ')
        p_cmd.timeout = time.time() + (float(cmdline.options.timeout)-1)
        p_cmd.proc = subprocess.Popen(exe,
                                      stdin = subprocess.PIPE,
                                      stdout = subprocess.PIPE,
                                      stderr = subprocess.PIPE,
                                      env = os.environ,
                                      preexec_fn = p_cmd._pre_execute_())
        while p_cmd.proc.poll() is None:
            if time.time() > p_cmd.timeout:
                p_cmd.timedout = True
                break
            time.sleep(0.1)
        self.__get_output(p_cmd)
        p_cmd.retcode = p_cmd.proc.returncode
        p_cmd._post_execute_()
        if p_cmd.retcode:
            self.__cmgr.completed_error.append(p_cmd)
        else:
            self.__cmgr.completed_success.append(p_cmd)
            if cmdline.options.wait:
                self.__log.debug('Waiting for %s seconds.'%cmdline.options.wait)
                time.sleep(float(cmdline.options.wait))

    def run(self):
        """Get a job and process it.  Stop when there are no more jobs.
        """
        while True:
            job = self.__get_job()
            if job is None:
                break
            self._process_job(job)
